MacでSDL2ライブラリを静的リンクしようと思ったら罠だらけで大変だったのでメモ。SDL2_imageなど、SDL2_hoge シリーズ も同様にしてできました。
学校の課題でSDL2のdylibを使ったプログラムを提出したら、実行時エラーが出ると言われ、修正を要請されました。コンパイラのインクルードパスやライブラリサーチパスは相対化しておいたのでコンパイルはできるようですが、実行時にdylibがないと怒られます。調べたところdylibは内部で自分のインストール時の絶対パスを保存していて、コンパイルのリンク時にそのパスを教えてくるみたいです。そのためdylibのフルパスをインストール時のものから変更すると実行ファイル側でdylibの場所がわからなくなるようです。
状況
- SDL2は自分のPCでコンパイル・インストール
(./configure –prefix=hogehoge でインストール先を指定している)
-
コンパイル済みSDL2を自分が作ったSDL2を利用したプログラムと一緒に別PCに(メールで)送る(自分が作ったプログラムはソースのみ送る)
-
別PCで自分が作ったプログラムがコンパイルされ、実行される。この時のパスは不明。
-
別PCは自分のPCと基本的な環境が同じであることが保証されている。
静的リンクの方法
やり方自体は簡単で SDl2のインストール先フォルダのlib下にあるlibSDL2.dylib(エイリアス)を削除して自分が作ったプログラムのコンパイル時にsdl2-config -static-libs に相当するオプションをつけるだけです。
libSDL2.dylibがあると -lSDL2 のリンクが指すものがそいつになってしまって動的リンクになるのですが、これを削除するとlibSDL2.aを指すようになって静的にリンクしてくれます。Linuxなら -Wl,-dn,-lSDL2 とか -Wl,-Bstatic,-lSDL2 のオプションをつけるとその部分だけ静的リンクしてくれるらしいですがMacではこれらのオプションは使えないみたいです。Macにもちゃんとしたオプションがあるのかもしれません。
おまけ 動的リンクのまま解決する方法
静的リンクになかなかできなかったので動的リンクで解決する方法もいろいろ考えました。
1.SDL2自体を送った先のPCでコンパイル・インストールさせる
通常ならこれが正攻法だと思います。ただし今回の場合、生徒全員がこれをやると指導者側が何十回もSDLのコンパイルを見届けることになってつらくて仕方ないはずです。また、SDL2のソースは60MBくらいあった気がするのでメールで送るという条件が厳しそうです。
2.DYLD_LIBRARY_PATH に libSDL2.dylib のフォルダのパスを通す
友人に教えてもらった方法。シンプルではあるがターミナルを立ち上げるごとにやらないといけない。
3.install_name_tool で libSDL2.dylibの内部に記録されたインストールパスを現在のパスに書き換える
かなり無理矢理感がありますが、dylibを今後移動させないなら1回きりでOK。
install_name_tool -id (libSDL2.dylibのフルパス) (libSDL2.dylibのパス)
# 例
install_name_tool -id /home/lib/libSDL2.dylib ./libSDL2.dylib
SDL2だけならいいですがSDL2_imageとかを使っているとSDL2_imageのdylib内部でSDL2のdylibが使われていて、それのパスも変更しないといけないので install_name_tool -change で頑張らないといけません。これは実際にやっていないので動くか知りませんが。